#include "taiic_opencv.h"

int64_t getCurrentTimeUs()
{
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return tv.tv_sec * 1000000 + tv.tv_usec;
}

void taiic_nv12_rgb(void *src, RK_U8 *dst, int sw, int sh)
{
    cv::Mat nv12_mat(sh + sh / 2, sw, CV_8UC1, (uchar *)src); // nv12.data
    cv::Mat gray_mat(sh, sw, CV_8UC1);
    cv::Mat rgb_mat(sh, sw, CV_8UC3);

    if (!nv12_mat.empty())
    {
        cv::cvtColor(nv12_mat, gray_mat, cv::COLOR_YUV2GRAY_NV12);
        // RK_LOGD("===gray_mat  size is %d==\n", gray_mat.total() * gray_mat.channels());
        cv::cvtColor(gray_mat, rgb_mat, cv::COLOR_GRAY2RGB);
        // RK_LOGD("===rgb_mat  size is %d==\n", rgb_mat.total()  * rgb_mat.channels());

        // cv::cvtColor(nv12_mat, rgb_mat, cv::COLOR_YUV2RGB_NV12);

        // }
        memcpy(dst, rgb_mat.data, (sh * sw * 3));

        // cv::imwrite("/data/hhh.jpg",rgb_mat);
    }
}

char save_pic[256] = {0}; // 蓝牙模式，发送蓝牙AT指令

void taiic_y_rgb(RK_U8 *src, RK_U8 *dst, int sw, int sh)
{
    cv::Mat gray_mat(sh, sw, CV_8UC1, (uchar *)src); // only y.data
    cv::Mat rgb_mat = cv::Mat::zeros(gray_mat.size(), CV_8UC3);
    if (!gray_mat.empty())
    {
        cv::cvtColor(gray_mat, rgb_mat, cv::COLOR_GRAY2RGB);
    }
    memcpy(dst, rgb_mat.data, (sh * sw * 3));
}

void taiic_gray_crop_resize(RK_U8 *src, RK_U8 *dst, int sw, int sh, int box_left, int box_top, int box_right, int box_bottom, int re_sw, int re_sh)
{
    cv::Mat rgb_mat(sw, sh, CV_8UC3, src);
    cv::Mat gray_mat(sw, sh, CV_8UC1);
    cv::cvtColor(rgb_mat, gray_mat, cv::COLOR_RGB2GRAY);
    RK_LOGD("===rgb to gray==\n");

    cv::Rect rect(box_left, box_top, (box_right - box_left), (box_bottom - box_top));
    cv::Mat cropped_img = gray_mat(rect);
    RK_LOGD("===crop==\n");

    cv::Mat resized_mat;
    cv::resize(cropped_img, resized_mat, cv::Size(re_sw, re_sh));
    RK_LOGD("===resize==\n");

    memcpy(dst, resized_mat.data, (re_sw * re_sh));

}

void taiic_gray_resize(RK_U8 *src, RK_U8 *dst, int sw, int sh, int re_sw, int re_sh)
{
    cv::Mat rgb_mat(sh, sw, CV_8UC3, src);
    cv::Mat gray_mat(sh, sw, CV_8UC1);
    cv::cvtColor(rgb_mat, gray_mat, cv::COLOR_RGB2GRAY);
    // RK_LOGD("===rgb -> gray==\n");

    cv::Mat resized_mat;
    cv::resize(gray_mat, resized_mat, cv::Size(re_sw, re_sh));
    RK_LOGI("===resized_mat  size is %d==\n", resized_mat.total() * resized_mat.channels());
    memcpy(dst, resized_mat.data, (re_sw * re_sh));

  
}

void taiic_y_crop_resize(RK_U8 *src, RK_U8 *dst, int sw, int sh, int box_left, int box_top, int box_right, int box_bottom, int re_sw, int re_sh)
{
    cv::Mat gray_mat(sw, sh, CV_8UC1, (uchar *)src);
    RK_LOGD("===gray==\n");

    cv::Rect rect(box_left, box_top, (box_right - box_left), (box_bottom - box_top));
    cv::Mat cropped_mat = gray_mat(rect);
    RK_LOGD("===crop==\n");

    cv::Mat resized_mat(re_sh, re_sw, CV_8UC1);
    cv::resize(cropped_mat, resized_mat, cv::Size(re_sw, re_sh));
    RK_LOGD("===resize==\n");

    memcpy(dst, resized_mat.data, (re_sw * re_sh));
}

void taiic_y_resize(RK_U8 *src, RK_U8 *dst, int sw, int sh, int re_sw, int re_sh)
{
    cv::Mat gray_mat(sh, sw, CV_8UC1, (uchar *)src); // 112 * 112
    cv::Mat resized_mat(re_sh, re_sw, CV_8UC1);      // 32 * 32

    cv::resize(gray_mat, resized_mat, cv::Size(re_sw, re_sh));
    RK_LOGD("===resized_mat  size is %d==\n", resized_mat.total() * resized_mat.channels());
    memcpy(dst, resized_mat.data, (re_sw * re_sh));

}

void taiic_y_resize_crop_resize(RK_U8 *src, RK_U8 *dst, int sw, int sh, int ori_w, int ori_h, int box_left, int box_top, int box_right, int box_bottom, int re_sw, int re_sh)
{
    cv::Mat gray_mat(sw, sh, CV_8UC1, (uchar *)src); // 112 * 112
    RK_LOGD("===gray==\n");

    cv::Mat ori_mat(ori_w, ori_h, CV_8UC1);
    cv::resize(gray_mat, ori_mat, cv::Size(ori_w, ori_w)); // 320 * 320
    RK_LOGD("===ori===\n");

    cv::Rect rect(box_left, box_top, (box_right - box_left), (box_bottom - box_top)); // crop
    cv::Mat cropped_mat = ori_mat(rect);
    RK_LOGD("===crop==\n");

    cv::Mat resized_mat(re_sh, re_sw, CV_8UC1); // 32 * 32
    cv::resize(cropped_mat, resized_mat, cv::Size(re_sw, re_sh));
    RK_LOGD("===resized==\n");


    memcpy(dst, resized_mat.data, (re_sw * re_sh));
}

void taiic_center_crop(RK_U8 *src, RK_U8 *dst, int sw, int sh, int re_sw, int re_sh)
{
    cv::Mat gray_mat(sh, sw, CV_8UC1, (uchar *)src);

	// 计算中心裁剪的起始坐标  
	 int x = (gray_mat.cols - re_sw) / 2; // 中心点的 x 坐标  
	 int y = (gray_mat.rows - re_sh) / 2; // 中心点的 y 坐标	

	//RK_LOGI("x:%d, y:%d, cols:%d, rows:%d", x, y, gray_mat.cols, gray_mat.rows);
    // 确保裁剪区域在图像范围内  
    if (x < 0 || y < 0 || x + re_sw > gray_mat.cols || y + re_sh > gray_mat.rows) {  
        RK_LOGE("Error: Crop area exceeds image boundaries.");  
        return;  
    }

	// 使用 cv::Rect 定义裁剪区域  
    cv::Rect roi(x, y, re_sw, re_sh); // 创建矩形区域 roi  

    // 裁剪图像  
    cv::Mat croppedImage = gray_mat(roi); // 使用 roi 来裁剪  
	//RK_LOGI("cropped image, cols:%d, rows:%d", croppedImage.cols, croppedImage.rows);

    //snprintf(save_pic, sizeof(save_pic), "%s%d%s", "/data/pic/crop", count++, ".jpg");
    //cv::imwrite(save_pic, croppedImage);

    for (int i = 0; i < re_sh; ++i) {  
        for (int j = 0; j < re_sw; ++j) {  
            dst[i * re_sw + j] = croppedImage.at<uchar>(i, j);  // 访问每个像素值  
        }  
    }
	//memcpy(dst, croppedImage.data, (re_sw * re_sh));
}